package common

import (
	"crypto/sha1"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"github.com/astaxie/beego/logs"
	"io"
	"math/rand"
	"mime/multipart"
	"net/http"
	"os"
	"path"
	"time"
)

var httpClient = &http.Client{
	Transport: &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	},
	Timeout: 0,
}

// SHA1 sha1
func SHA1(s string) string {
	o := sha1.New()
	o.Write([]byte(s))
	return hex.EncodeToString(o.Sum(nil))
}

// FileExist 是否存在
func FileExist(path string) bool {
	_, err := os.Lstat(path)
	return !os.IsNotExist(err)
}

// DownloadToLocalUseCache 下载
func DownloadToLocalUseCache(url string) (filePath, fileName string) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		logs.Error(err)
		return
	}
	res, err := httpClient.Do(req)
	if err != nil {
		logs.Error(err)
		return
	}
	defer res.Body.Close()

	fileName = path.Base(url)
	fileExt := path.Ext(fileName)
	fileSha1 := SHA1(url)
	filePath = "/tmp/" + fileSha1 + fileExt

	if FileExist(filePath) {
		return
	}

	f, err := os.Create(filePath)
	if err != nil {
		logs.Error(err)
		return "", ""
	}
	defer f.Close()
	io.Copy(f, res.Body)
	return
}

// RemoveCacheFromURL 删除缓存文件
func RemoveCacheFromURL(url string) {
	fileSha1 := SHA1(url)
	fileName := path.Base(url)
	fileExt := path.Ext(fileName)
	filePath := "/tmp/" + fileSha1 + fileExt
	os.Remove(filePath)
}

// TempDir 创建临时文件夹
func TempDir() string {
	timeKey := time.Now().Format("200601")
	fileDir := "./temp/" + timeKey + "/"
	dirExists, _ := PathExists(fileDir)
	if dirExists == false {
		_ = os.MkdirAll(fileDir, os.ModePerm)
	}
	return fileDir
}

// TempFile 临时存储文件
func TempFile(file multipart.File, fileHeader *multipart.FileHeader) (string, string, error) {
	timeKey := time.Now().Format("200601")
	fileDir := "./tmp/" + timeKey + "/"
	ext := GetExt(fileHeader.Filename)
	fileName := GetRandomString(16) + ext
	err := IsNotExistMkDir(fileDir)
	if err != nil {
		return "", "", err
	}
	singleFile := fileDir + fileName
	_ = SaveUploadedFile(file, singleFile)
	return singleFile, fileName, nil
}
func TempFileConvert(url, filename string) (string, string, error) {
	res, _ := http.Get(url)
	defer res.Body.Close()
	timeKey := time.Now().Format("200601")
	fileDir := "./tmp/" + timeKey + "/"
	singleFile := fileDir + filename
	IsNotExistMkDir(fileDir)
	out, err := os.Create(singleFile)
	fmt.Println(err)
	io.Copy(out, res.Body)
	defer out.Close()
	return singleFile, filename, nil
}

func TempFileExt(file multipart.File, ext string) (string, string, error) {
	timeKey := time.Now().Format("200601")
	fileDir := "./tmp/" + timeKey + "/"
	fileName := GetRandomString(16) + ext
	err := IsNotExistMkDir(fileDir)
	if err != nil {
		return "", "", err
	}
	singleFile := fileDir + fileName
	_ = SaveUploadedFile(file, singleFile)
	return singleFile, fileName, nil
}

// GetExt 获取文件后缀
func GetExt(fileName string) string {
	return path.Ext(fileName)
}

// CheckExist 检查文件是否存在
func CheckExist(src string) bool {
	_, err := os.Stat(src)

	return os.IsNotExist(err)
}

// IsNotExistMkDir 检查文件夹是否存在
// 如果不存在则新建文件夹
func IsNotExistMkDir(src string) error {
	if exist := !CheckExist(src); exist == false {
		if err := MkDir(src); err != nil {
			return err
		}
	}

	return nil
}

// MkDir 新建文件夹
func MkDir(src string) error {
	err := os.MkdirAll(src, os.ModePerm)
	if err != nil {
		return err
	}

	return nil
}

func SaveUploadedFile(file multipart.File, dst string) error {
	out, err := os.Create(dst)
	if err != nil {
		return err
	}
	_, err = io.Copy(out, file)
	return err
}

// PathExists 路径是否存在
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// GetRandomString 生成随机字符串
func GetRandomString(n int) string {
	const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, n)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := range b {
		b[i] = letterBytes[r.Int63()%int64(len(letterBytes))]
	}
	return string(b)
}
